/*
 * ECARX Technology Limited is the owner of the copyright and the trade secret of this software.
 * Without permission, no one has the right to obtain, disclose or use this software in any way.
 */

package com.ecarx.systemui.plugin.controller.hvac;

import android.car.VehicleAreaSeat;
import android.car.VehiclePropertyIds;
import android.car.VehicleUnit;
import android.car.hardware.CarPropertyValue;
import android.car.hardware.property.CarPropertyManager;

import com.ecarx.systemui.plugin.controller.CarSignalController;
import com.ecarx.systemui.plugin.model.listener.TempFuncNotifyViewListener;
import com.ecarx.systemui.plugin.utils.LogUtils;
import com.ecarx.systemui.plugin.utils.ThreadUtils;
import com.ecarx.xui.adaptapi.FunctionStatus;

@SuppressWarnings("SameParameterValue")
public class TempSignalController extends HvacBaseController implements CarPropertyManager.CarPropertyEventCallback {

    private static final String TAG = "TempSignalControllerTag";
    public static final float MAX_TEMP_C = 28.5F;
    public static final float MIN_TEMP_C = 15.5F;

    public static final float MAX_TEMP_F = 85F;
    public static final float MIN_TEMP_F = 59F;

    public static final float TEMP_STEP_C = 0.5F;
    public static final float TEMP_STEP_F = 1F;

    private TempFuncNotifyViewListener mTempLeftNotifyViewListener;
    private TempFuncNotifyViewListener mTempRightNotifyViewListener;

    public void setTempLeftNotifyViewListener(TempFuncNotifyViewListener tempFuncNotifyViewListener) {
        this.mTempLeftNotifyViewListener = tempFuncNotifyViewListener;
        initDriverTemp();
    }

    public void setTempRightNotifyViewListener(TempFuncNotifyViewListener tempFuncNotifyViewListener) {
        this.mTempRightNotifyViewListener = tempFuncNotifyViewListener;
        initPassengerTemp();
    }

    private TempSignalController() {
        doRegisterSignal();
    }

    private static TempSignalController tempSignalController;

    public static synchronized TempSignalController getInstance() {
        if (tempSignalController == null) {
            tempSignalController = new TempSignalController();
        }
        return tempSignalController;
    }

    private void doRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            ThreadUtils.postDelayOnMain(100, new Runnable() {
                @Override
                public void run() {
                    doRegisterSignal();
                }
            });
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.registerCallback(this, VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);//float
        carPropertyManager.registerCallback(this, VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4); //float
        carPropertyManager.registerCallback(this, VehiclePropertyIds.HVAC_DUAL_ON, 117); // true false
        carPropertyManager.registerCallback(this, VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0); // int

        if (mTempLeftNotifyViewListener != null) {
            initDriverTemp();
        }

        if (mTempRightNotifyViewListener != null) {
            initPassengerTemp();
        }

    }

    private void doUnRegisterSignal() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.unregisterCallback(this);
    }

    private void initDriverTemp() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (!isDriverHvacTemperatureSetAvailable()) {
            return;
        }
        float floatProperty = carPropertyManager.getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);
        boolean propertyAvailable = carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);
        LogUtils.d(TAG, "HVAC_TEMPERATURE_SET driver isPropertyAvailable:" + propertyAvailable);
        if (propertyAvailable) {
            mTempLeftNotifyViewListener.onDriverTempChanged(floatProperty, FunctionStatus.active);
        } else {
            mTempLeftNotifyViewListener.onDriverTempChanged(floatProperty, FunctionStatus.notactive);
        }

        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return;
        }
        int intProperty = carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        boolean propertyAvailable1 = carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        if (propertyAvailable1) {
            mTempLeftNotifyViewListener.onTempUnitChanged(intProperty, floatProperty, FunctionStatus.active);
        } else {
            mTempLeftNotifyViewListener.onTempUnitChanged(intProperty, floatProperty, FunctionStatus.notactive);
        }

    }

    private void initPassengerTemp() {
        boolean isOk = CarSignalController.checkSelf();
        if (!isOk) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        if (!isPassengerHvacTemperatureSetAvailable()) {
            return;
        }
        float floatProperty = carPropertyManager.getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, VehicleAreaSeat.SEAT_ROW_1_RIGHT);
        boolean propertyAvailable = carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4);
        LogUtils.d(TAG, "HVAC_TEMPERATURE_SET passenger isPropertyAvailable:" + propertyAvailable);
        if (propertyAvailable) {
            mTempRightNotifyViewListener.onPassengerTempChanged(floatProperty, FunctionStatus.active);
        } else {
            mTempRightNotifyViewListener.onPassengerTempChanged(floatProperty, FunctionStatus.notactive);
        }

        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return;
        }
        int intProperty = carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        boolean propertyAvailable1 = carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        if (propertyAvailable1) {
            mTempRightNotifyViewListener.onTempUnitChanged(intProperty, floatProperty, FunctionStatus.active);
        } else {
            mTempRightNotifyViewListener.onTempUnitChanged(intProperty, floatProperty, FunctionStatus.notactive);
        }
    }


    public boolean isSyncSupport() {
        if (!isHvacDualOnAvailable()) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.isPropertyAvailable(VehiclePropertyIds.HVAC_DUAL_ON, 117);
    }

    /*
     *  摄氏度 15.5 - 28.5   调节单位 0.5
     *  华氏度 59  -  85     调节单位1
     *
     * */

    public float driverTempDown() { //-
        if (!isDriverHvacTemperatureSetAvailable()) {
            return 255;
        }

        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return 255;
        }

        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        float tempValue = carPropertyManager
                .getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);
        int tempUnit = carPropertyManager
                .getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        float TEMP_STEP;
        float minTemp;
        if (VehicleUnit.CELSIUS == tempUnit) {
            TEMP_STEP = TEMP_STEP_C;
            minTemp = MIN_TEMP_C;
        } else {
            TEMP_STEP = TEMP_STEP_F;
            minTemp = MIN_TEMP_F;
        }
        tempValue = tempValue - TEMP_STEP;
        if (tempValue <= minTemp) {
            tempValue = minTemp;
        }
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1, tempValue);
        return tempValue;
    }

    public float driverTempUp() { //+
        if (!isDriverHvacTemperatureSetAvailable()) {
            return 255;
        }

        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return 255;
        }

        CarPropertyManager carPropertyManager =
                CarSignalController.getInstance().getCarPropertyManager();
        float tempValue = carPropertyManager.getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);
        int tempUnit = carPropertyManager
                .getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        float TEMP_STEP;
        float maxTemp;
        if (VehicleUnit.CELSIUS == tempUnit) {
            TEMP_STEP = TEMP_STEP_C;
            maxTemp = MAX_TEMP_C;
        } else {
            TEMP_STEP = TEMP_STEP_F;
            maxTemp = MAX_TEMP_F;
        }
        tempValue = tempValue + TEMP_STEP;
        if (tempValue >= maxTemp) {
            tempValue = maxTemp;
        }
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1, tempValue);
        return tempValue;
    }

    public float passengerTempDown() {
        if (!isPassengerHvacTemperatureSetAvailable()) {
            return 255;
        }
        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        float floatProperty = carPropertyManager
                .getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4);
        int tempUnit = carPropertyManager
                .getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        float min_temp;
        float TEMP_STEP;
        if (VehicleUnit.CELSIUS == tempUnit) {
            min_temp = MIN_TEMP_C;
            TEMP_STEP = TEMP_STEP_C;
        } else {
            min_temp = MIN_TEMP_F;
            TEMP_STEP = TEMP_STEP_F;
        }
        floatProperty = floatProperty - TEMP_STEP;
        if (floatProperty <= min_temp) {
            floatProperty = min_temp;
        }
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4, floatProperty);
        return floatProperty;
    }


    public float passengerTempUp() {
        if (!isPassengerHvacTemperatureSetAvailable()) {
            return 255;
        }
        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        float tempValue = carPropertyManager
                .getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4);
        int tempUnit = carPropertyManager
                .getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
        float TEMP_STEP;
        float maxTemp;
        if (VehicleUnit.CELSIUS == tempUnit) {
            TEMP_STEP = TEMP_STEP_C;
            maxTemp = MAX_TEMP_C;
        } else {
            TEMP_STEP = TEMP_STEP_F;
            maxTemp = MAX_TEMP_F;
        }
        tempValue = tempValue + TEMP_STEP;
        if (tempValue >= maxTemp) {
            tempValue = maxTemp;
        }
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4, tempValue);
        return tempValue;
    }

    public void setDriverTemp(Float value) {
        if (!isDriverHvacTemperatureSetAvailable()) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1, value);
    }

    public void setPassengerTemp(Float value) {
        if (!isPassengerHvacTemperatureSetAvailable()) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.setFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4, value);
    }

    public float getDriverTempValue() {
        if (!isDriverHvacTemperatureSetAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 1);
    }

    public float getPassengerTempValue() {
        if (!isPassengerHvacTemperatureSetAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getFloatProperty(VehiclePropertyIds.HVAC_TEMPERATURE_SET, 4);
    }

    public boolean getSyncValue() {
        if (!isHvacDualOnAvailable()) {
            return false;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getBooleanProperty(VehiclePropertyIds.HVAC_DUAL_ON, 117);
    }

    public void setSyncValue(boolean syncValue) {
        if (!isHvacDualOnAvailable()) {
            return;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        carPropertyManager.setBooleanProperty(VehiclePropertyIds.HVAC_DUAL_ON, 117, syncValue);

    }

    public int getTempUnit() {
        if (!isHVACTemperatureDisplayUnitsAvailable()) {
            return 255;
        }
        CarPropertyManager carPropertyManager = CarSignalController.getInstance().getCarPropertyManager();
        return carPropertyManager.getIntProperty(VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS, 0);
    }

    @Override
    public void onChangeEvent(CarPropertyValue carPropertyValue) {
        LogUtils.d(TAG, "carPropertyValue:" + carPropertyValue.toString());
        int propertyId = carPropertyValue.getPropertyId();
        int areaId = carPropertyValue.getAreaId();
        int status = carPropertyValue.getStatus();
        FunctionStatus functionStatus = CarSignalController.toFunctionStatus(status);
        Object value = carPropertyValue.getValue();
        switch (propertyId) {
            case VehiclePropertyIds.HVAC_TEMPERATURE_SET:
                Float tempValue = (Float) value;
                if (1 == areaId) {
                    if (mTempLeftNotifyViewListener != null) {
                        mTempLeftNotifyViewListener.onDriverTempChanged(tempValue, functionStatus);
                    }
                } else if (4 == areaId) {
                    if (mTempRightNotifyViewListener != null) {
                        mTempRightNotifyViewListener.onPassengerTempChanged(tempValue, functionStatus);
                    }
                }
                break;
            case VehiclePropertyIds.HVAC_DUAL_ON:
                boolean isSync = (boolean) value;
                if (mTempLeftNotifyViewListener != null) {
                    mTempLeftNotifyViewListener.onTempSyncChanged(isSync, functionStatus);
                }
                if (mTempRightNotifyViewListener != null) {
                    mTempRightNotifyViewListener.onTempSyncChanged(isSync, functionStatus);
                }
                break;
            case VehiclePropertyIds.HVAC_TEMPERATURE_DISPLAY_UNITS:
                int tempUnit = (int) value;
                if (mTempLeftNotifyViewListener != null) {
                    float driverTempValue = getDriverTempValue();
                    mTempLeftNotifyViewListener.onTempUnitChanged(tempUnit, driverTempValue, functionStatus);
                }
                if (mTempRightNotifyViewListener != null) {
                    float passengerTempValue = getPassengerTempValue();
                    mTempRightNotifyViewListener.onTempUnitChanged(tempUnit, passengerTempValue, functionStatus);
                }
                break;
        }
    }

    @Override
    public void onErrorEvent(int i, int i1) {

    }
}
